package ar.com.angrymachine.gameui;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Vector;

public class GameCanvas extends Canvas implements MouseListener, MouseMotionListener, Runnable
{
	private static final long serialVersionUID = 1L;
	private Image backBuffer;
    private Graphics backBufferGC;
    protected Vector widgets = new Vector(); // top level widgets
    public static GameCanvas screen;
    private Widget modalWidget = null;
    private Widget mouseCapturing = null;
    public Theme theme;

    public GameCanvas(Theme theme)
    {
        screen = this;
        addMouseListener(this);
        addMouseMotionListener(this);
        this.theme = theme;
    }
    
    Graphics getCurrentGraphics()
    {
    	return backBufferGC;
    }
    
    public void showWidgetModal(Widget widget)
    {
    	modalWidget = widget;
    	showWidget(widget);
    }
    
    public void showWidget(Widget widget)
    {
    	widgets.add(widget);
    }
    
    public void clear()
    {
    	widgets.clear();
    }

    public void run()
    {
        for (int i = 0; i < widgets.size(); i++)
        {
            Widget w = (Widget) widgets.elementAt(i);
            w.managerRun();
        }
        repaint();
    }
    
    protected void finalize() throws Throwable
    {
        try
        {
            backBufferGC.dispose();
        }
        finally
        {
            super.finalize();
        }
    }

	public void deleteWidget(Widget widget)
	{
		widgets.remove(widget);
		if(widget == modalWidget)
		{
			modalWidget = null;
		}
	}

	public void mouseClicked(MouseEvent arg0)
	{
	}

	public void mouseEntered(MouseEvent arg0)
	{
		// TODO Auto-generated method stub
		
	}

	public void mouseExited(MouseEvent arg0)
	{
		// TODO Auto-generated method stub
		
	}
	
	void mouseCapture(Widget capturing)
	{
		mouseCapturing = capturing;
	}
	
	void mouseRelease()
	{
		mouseCapturing = null;
	}

	public void mousePressed(MouseEvent arg0)
	{
		if(mouseCapturing != null)
		{
			mouseCapturing.mouseDown(mouseCapturing.screenToWidget(new Point(arg0.getX(), arg0.getY())));
		}
		else
		if(modalWidget != null)
		{
			modalWidget.managerMouseDown(new Point(arg0.getX(), arg0.getY()));
		}
		else
		{
	        for (int i = 0; i < widgets.size(); i++)
	        {
	            Widget w = (Widget) widgets.elementAt(i);
	            if (w.managerMouseDown(new Point(arg0.getX(), arg0.getY())) != null)
	            {
	                break;
	            }
	        }
		}
	}

	public void mouseReleased(MouseEvent arg0)
	{
		if(mouseCapturing != null)
		{
			mouseCapturing.mouseUp(mouseCapturing.screenToWidget(new Point(arg0.getX(), arg0.getY())));
		}
		else
		if(modalWidget != null)
		{
			modalWidget.managerMouseUp(new Point(arg0.getX(), arg0.getY()));
		}
		else
		{
	        for (int i = 0; i < widgets.size(); i++)
	        {
	            Widget w = (Widget) widgets.elementAt(i);
	            if (w.managerMouseUp(new Point(arg0.getX(), arg0.getY())) != null)
	            {
	                break;
	            }
	        }
		}
	}

	public void paint(Graphics g)
	{
        if(backBuffer == null)
        {
        	System.out.println("w:"+getSize().width+" h:"+getSize().height);
            backBuffer = createImage(getSize().width, getSize().height);
            backBufferGC = backBuffer.getGraphics();
            backBufferGC.setColor(Color.RED);
            System.out.println("w:"+backBuffer.getWidth(null)+" h:"+getSize().height);
            backBufferGC.fillRect(0,0,backBuffer.getWidth(null),backBuffer.getHeight(null));
        }
        Graphics screenGraphics = g;
        g = backBufferGC;
        for (int i = 0; i < widgets.size(); i++)
        {
            Widget w = (Widget) widgets.elementAt(i);
            w.managerPaint(g);
        }        
        screenGraphics.drawImage(backBuffer, 0, 0, null);
	}
	
	public void update(Graphics g)
	{
		paint(g);
	}
	
    public Image loadImage(String file)
    {
        Toolkit t = getToolkit();
        Image img = t.getImage(file);
        MediaTracker m = new MediaTracker(this);
        m.addImage( img, 1 );
        try
        {
        	m.waitForAll();
        }
        catch( InterruptedException e )
        {
        }
        return img;
    }

	public void mouseDragged(MouseEvent arg0)
	{
		//TODO: make this generic
		if(mouseCapturing != null)
		{
			mouseCapturing.mouseMoved(mouseCapturing.screenToWidget(new Point(arg0.getX(), arg0.getY())));
		}
	}

	public void mouseMoved(MouseEvent arg0)
	{
	}
	
	public void destroyWidget(Widget widget)
	{
    	if(widget.parent != null)
    	{
    		widget.setParent(null);
    	}
    	widgets.remove(widget);
    	if(modalWidget == widget)
    	{
    		modalWidget = null;
    	}
    	if(mouseCapturing == widget)
    	{
    		mouseRelease();
    	}
	}

}
